From e5006ce0f0365f0702c8d7b0a66bb51eb0d2f257 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Mon, 12 Jun 2017 12:54:24 -0400 Subject: [PATCH] API: Restore ability for dieStatus() to be passed a non-fatal Status This ability was accidentally removed in Iae0e2ce3. Bug: T167690 Change-Id: I79cc9f2f8e75c3cf4e0942d17faafa84955aa020 --- includes/api/ApiBase.php | 17 ++++++++++ tests/phpunit/includes/api/ApiBaseTest.php | 39 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index a6c4b2ad19..5332d7e07f 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1863,6 +1863,23 @@ abstract class ApiBase extends ContextSource { throw new MWException( 'Successful status passed to ApiBase::dieStatus' ); } + // ApiUsageException needs a fatal status, but this method has + // historically accepted any non-good status. Convert it if necessary. + $status->setOK( false ); + if ( !$status->getErrorsByType( 'error' ) ) { + $newStatus = Status::newGood(); + foreach ( $status->getErrorsByType( 'warning' ) as $err ) { + call_user_func_array( + [ $newStatus, 'fatal' ], + array_merge( [ $err['message'] ], $err['params'] ) + ); + } + if ( !$newStatus->getErrorsByType( 'error' ) ) { + $newStatus->fatal( 'unknownerror-nocode' ); + } + $status = $newStatus; + } + throw new ApiUsageException( $this, $status ); } diff --git a/tests/phpunit/includes/api/ApiBaseTest.php b/tests/phpunit/includes/api/ApiBaseTest.php index 253ac959ff..ee0ad946bd 100644 --- a/tests/phpunit/includes/api/ApiBaseTest.php +++ b/tests/phpunit/includes/api/ApiBaseTest.php @@ -174,4 +174,43 @@ class ApiBaseTest extends ApiTestCase { ], $user ) ); } + /** + * @covers ApiBase::dieStatus + */ + public function testDieStatus() { + $mock = new MockApi(); + + $status = StatusValue::newGood(); + $status->error( 'foo' ); + $status->warning( 'bar' ); + try { + $mock->dieStatus( $status ); + $this->fail( 'Expected exception not thrown' ); + } catch ( ApiUsageException $ex ) { + $this->assertTrue( ApiTestCase::apiExceptionHasCode( $ex, 'foo' ), 'Exception has "foo"' ); + $this->assertFalse( ApiTestCase::apiExceptionHasCode( $ex, 'bar' ), 'Exception has "bar"' ); + } + + $status = StatusValue::newGood(); + $status->warning( 'foo' ); + $status->warning( 'bar' ); + try { + $mock->dieStatus( $status ); + $this->fail( 'Expected exception not thrown' ); + } catch ( ApiUsageException $ex ) { + $this->assertTrue( ApiTestCase::apiExceptionHasCode( $ex, 'foo' ), 'Exception has "foo"' ); + $this->assertTrue( ApiTestCase::apiExceptionHasCode( $ex, 'bar' ), 'Exception has "bar"' ); + } + + $status = StatusValue::newGood(); + $status->setOk( false ); + try { + $mock->dieStatus( $status ); + $this->fail( 'Expected exception not thrown' ); + } catch ( ApiUsageException $ex ) { + $this->assertTrue( ApiTestCase::apiExceptionHasCode( $ex, 'unknownerror-nocode' ), + 'Exception has "unknownerror-nocode"' ); + } + } + } -- 2.20.1